package com.iot08.api.service;

import com.iot08.api.response.GoldCoinBuyerOrderDataResp;
import com.iot08.api.response.GoldCoinBuyerOrderResp;
import com.iot08.api.vo.request.GoldCoinBuyerOrderQueryReqVo;
import com.iot08.common.entity.app.GoldCoinBuyerServerRecord;
import com.iot08.common.entity.app.SmsNotifyServer;
import com.iot08.common.entity.app.StartEndTime;
import com.iot08.common.entity.app.Wallpaper;
import com.iot08.common.service.base.BaseService;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author cwj
 * @description
 * @date 2025/3/13 15:55
 **/
@Slf4j
@Service
public class GoldCoinBuyerServerRecordService extends BaseService<GoldCoinBuyerServerRecord> {


    /**
     * @description 创建用户购买壁纸信息的详细记录
     * @author cwj
     * @param [wallpapers, openId, orderId, serverName, type, status, serverTimes, desc]
     * @return void
     * @date @time 2025/3/13 17:17
     **/
    public void createWallpapperGoldCoinBuyerServerRecord(List<Wallpaper> wallpapers, String openId,String orderId,
                                                          String serverName,Integer type,Integer status,
                                                          Integer serverTimes,String desc){
        if(!CollectionUtils.isEmpty(wallpapers)) {
            List<GoldCoinBuyerServerRecord> goldCoinBuyerServerRecords = new ArrayList<>();
            for(Wallpaper w : wallpapers) {
                GoldCoinBuyerServerRecord gcb = buildingGoldCoinBuyerServerRecord(openId, orderId, serverName, type, status, serverTimes, desc, w.getId(),w.getPrice());
                goldCoinBuyerServerRecords.add(gcb);
            }
            mongoTemplate.insertAll(goldCoinBuyerServerRecords);
        }
    }

    /**
     * @description 创建用户购买短信通知服务的订单详情记录
     * @author cwj
     * @param [smsNotifyServer, openId, orderId, serverName, type, status, serverTimes, desc]
     * @return void
     * @date @time 2025/3/16 17:40
     **/
    public GoldCoinBuyerServerRecord  createSmsNotifyGoldCoinBuyerServerRecord(SmsNotifyServer smsNotifyServer,String openId,String orderId,String serverName,
                                                         Integer type,Integer status,Integer serverTimes,String desc){
        GoldCoinBuyerServerRecord gcb = buildingGoldCoinBuyerServerRecord(openId, orderId, serverName, type, status, serverTimes, desc,
                smsNotifyServer.getId(),smsNotifyServer.getPrice());
        return this.save(gcb);
    }

    /**
     * @description 构建
     * @author cwj
     * @param [openId, orderId, serverName, type, status, serverTimes, desc, w]
     * @return com.iot08.common.entity.app.GoldCoinBuyerServerRecord
     * @date @time 2025/3/16 17:38
     **/
    private GoldCoinBuyerServerRecord buildingGoldCoinBuyerServerRecord(String openId, String orderId, String serverName,
                                                                        Integer type, Integer status, Integer serverTimes,
                                                                        String desc, String serverId,Integer serverPrice) {
        GoldCoinBuyerServerRecord gcb = new GoldCoinBuyerServerRecord();
        gcb.setOpenid(openId);
        gcb.setUserBuyerOrderId(orderId);
        gcb.setWid(serverId);
        gcb.setServerName(serverName);
        gcb.setPrice(serverPrice);
        gcb.setGoldCoinTotal(serverPrice * serverTimes);
        gcb.setType(type);
        gcb.setStatus(status);
        gcb.setServerTimes(serverTimes);
        gcb.setDesc(desc);
        gcb.setCreateTime(new Date());
        gcb.setUpdateTime(new Date());
        return gcb;
    }

    /**
     * @description 查询用户用金币购买服务的订单信息
     * @author cwj
     * @param []
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/3/27 9:54
     **/
    /*public ResponseMap queryGoldCoinBuyerOrder(GoldCoinBuyerOrderQueryReqVo vo){
        int skip = vo.getPage() * vo.getNum();
        Aggregation countAggregation = Aggregation.newAggregation(
                // 筛选指定用户的 UserWallpaper 记录
                Aggregation.match(Criteria.where("openid").is(vo.getOpenid())),

                // 关联 Wallpaper 表，转换 wid 为 ObjectId 类型
                Aggregation.project()
                        .andExpression("{$toObjectId: '$userBuyerOrderId'}").as("userBuyerOrderObjectId"),
                // 使用 lookup 进行关联
                Aggregation.lookup("user_buyer_order", "userBuyerOrderObjectId", "_id", "userBuyerOrderData"),

                // 展开 wallpaperData（避免空值影响）
                Aggregation.unwind("userBuyerOrderData", true),

                // 投影出需要的字段（可以只保留 wallpaperData 的必要字段，减少计算复杂度）
                Aggregation.project("userBuyerOrderData._id"),

                // 统计符合条件的记录数
                Aggregation.count().as("totalCount")
        );
        // 执行总数查询
        AggregationResults<Document> countResults = mongoTemplate.aggregate(countAggregation, "user_buyer_server_record", Document.class);
        long totalCount = 0;
        if (!countResults.getMappedResults().isEmpty()) {
            totalCount = countResults.getMappedResults().get(0).getInteger("totalCount");
        }
        Aggregation aggregation = Aggregation.newAggregation(
                // 1️⃣ 筛选指定用户的 UserWallpaper 记录
                Aggregation.match(Criteria.where("openid").is(vo.getOpenid())),

                // 使用原生的 MongoDB 聚合操作 $toObjectId 转换 wid 字段
                Aggregation.project()
                        .andExpression("{$toObjectId: '$userBuyerOrderId'}").as("userBuyerOrderObjectId")
                        .and("_id").as("gbsId")  // 保留 `_id`
                        .and("wid").as("wid")
                        .and("serverName").as("serverName")
                        .and("price").as("price")
                        .and("goldCoinTotal").as("goldCoinTotal")
                        .and("type").as("type")
                        .and("status").as("status")
                        .and("serverTimes").as("serverTimes")
                        .and("desc").as("desc")
                        .and("createTime").as("orderRecordCreateTime"),
                // 使用 lookup 进行关联
                Aggregation.lookup("user_buyer_order", "userBuyerOrderObjectId", "_id", "userBuyerOrderData"),

                // 3️⃣ 展开 wallpaperData（避免空值影响）
                Aggregation.unwind("userBuyerOrderData", true),

                // 4️⃣ 投影出需要的字段
                Aggregation.project()
                        .andExpression("userBuyerOrderData._id").as("userBuyerOrderId")
                        .andExpression("userBuyerOrderData.openid").as("openid")
                        .andExpression("userBuyerOrderData.paymentTime").as("paymentTime")
                        .and("gbsId").as("gbsId")
                        .and("wid").as("wid")
                        .and("serverName").as("serverName")
                        .and("price").as("price")
                        .and("goldCoinTotal").as("goldCoinTotal")
                        .and("type").as("type")
                        .and("status").as("status")
                        .and("serverTimes").as("serverTimes")
                        .and("desc").as("desc")
                        //.and("orderRecordCreateTime").as("createTime")   // GoldCoinBuyerServerRecord 的 createTime 显示为 orderRecordCreateTime
                        .and("userBuyerOrderData.createTime").as("orderCreateTime")  // GoldCoinBuyerOrder 的 createTime 显示为 orderCreateTime
                        .andExpression("{$dateToString: { format: '%Y-%m-%d %H:%M:%S', date: '$orderRecordCreateTime' }}").as("createTime"),  // 这里转换
                // 5️⃣ 按 createTime 倒序排列
                Aggregation.sort(Sort.by(Sort.Direction.DESC, "createTime")),
                // 6️⃣ 分页处理
                Aggregation.skip(skip),
                Aggregation.limit(vo.getNum())
        );
        // 8️⃣ 执行查询
        List<GoldCoinBuyerOrderResp> goldCoinBuyerOrderResps = mongoTemplate.aggregate(aggregation, "user_buyer_server_record", GoldCoinBuyerOrderResp.class).getMappedResults();
        ResponseMap res = ResponseMap.success();
        res.put("total",totalCount);
        res.put("goldCoinBuyerOrderResps",goldCoinBuyerOrderResps);
        return res;
    }*/
    public ResponseMap queryGoldCoinBuyerOrder(GoldCoinBuyerOrderQueryReqVo vo) throws ParseException {
        Date endTime;
        Date startTime;
        StartEndTime startEndTime = DateUtil.assembleStartEndTime(vo.getDeadlineYear(),vo.getDeadlineMonth());
        endTime = startEndTime.getEndTime();
        startTime = startEndTime.getStartTime();
        Criteria criteria;
        if(ObjectUtils.isEmpty(startTime)) {
            criteria = Criteria.where("openid").is(vo.getOpenid()).and("status").is(1).and("createTime").lte(endTime);
        } else {
            criteria =Criteria.where("openid").is(vo.getOpenid()).and("status").is(1).and("createTime").gte(startTime).lte(endTime);
        }
        //聚合查询
        Aggregation aggregation = Aggregation.newAggregation(
                // 筛选user_buyer_server_record用户购买记录详情表的数据
                Aggregation.match(criteria),
                // 使用原生的 MongoDB 聚合操作 $toObjectId 转换 wid 字段
                Aggregation.project()
                        .andExpression("{$toObjectId: '$userBuyerOrderId'}").as("userBuyerOrderObjectId")
                       // .and("_id").as("gbsId")  // 保留 `_id`
                        //.and("wid").as("wid")
                        .and("serverName").as("serverName")
                        //.and("price").as("price")
                        .and("goldCoinTotal").as("goldCoinTotal")
                        .and("type").as("type")
                        //.and("status").as("status")
                        .and("serverTimes").as("serverTimes")
                        .and("desc").as("desc")
                        .and("createTime").as("orderRecordCreateTime"),
                // 使用 lookup 进行关联
                Aggregation.lookup("user_buyer_order", "userBuyerOrderObjectId", "_id", "userBuyerOrderData"),

                // 3️⃣ 展开 wallpaperData（避免空值影响）
                Aggregation.unwind("userBuyerOrderData", true),

                // 4️⃣ 投影出需要的字段
                Aggregation.project()
                        //.andExpression("userBuyerOrderData._id").as("userBuyerOrderId")
                        //.andExpression("userBuyerOrderData.openid").as("openid")
                        .andExpression("userBuyerOrderData.paymentTime").as("paymentTime")
                        //.and("gbsId").as("gbsId")
                        //.and("wid").as("wid")
                        .and("serverName").as("serverName")
                        //.and("price").as("price")
                        .and("goldCoinTotal").as("goldCoinTotal")
                        .and("type").as("type")
                        //.and("status").as("status")
                        .and("serverTimes").as("serverTimes")
                        .and("desc").as("desc")
                        //.and("orderRecordCreateTime").as("createTime")   // GoldCoinBuyerServerRecord 的 createTime 显示为 orderRecordCreateTime
                        .and("userBuyerOrderData.createTime").as("orderCreateTime")  // GoldCoinBuyerOrder 的 createTime 显示为 orderCreateTime
                        .andExpression("{$dateToString: { format: '%Y-%m-%d %H:%M:%S', date: '$orderRecordCreateTime' }}").as("createTime"),  // 这里转换
                // 5️⃣ 按 createTime 倒序排列
                Aggregation.sort(Sort.by(Sort.Direction.DESC, "createTime"))
        );
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtil.FORMAT_1);
        // 8️⃣ 执行查询
        List<GoldCoinBuyerOrderResp> goldCoinBuyerOrderResps = mongoTemplate.aggregate(aggregation, "user_buyer_server_record", GoldCoinBuyerOrderResp.class).getMappedResults();
        ResponseMap res = ResponseMap.success();
        if(CollectionUtils.isEmpty(goldCoinBuyerOrderResps)) {
            return res;
        } else {
            Map<String, List<GoldCoinBuyerOrderResp>> groupedOrders = goldCoinBuyerOrderResps.stream()
                    .collect(Collectors.groupingBy(order ->
                            LocalDateTime.parse(order.getCreateTime(), formatter).format(DateTimeFormatter.ofPattern("yyyy-MM"))
                    ));
            List<GoldCoinBuyerOrderDataResp> goldCoinBuyerOrderDataResps = new ArrayList<>();
            groupedOrders.forEach((date,orderResps)->{
                GoldCoinBuyerOrderDataResp dataResp = new GoldCoinBuyerOrderDataResp();
                dataResp.setDate(date);
                dataResp.setGoldCoinBuyerOrderResps(orderResps);
                goldCoinBuyerOrderDataResps.add(dataResp);
            });
            res.put("goldCoinBuyerOrderDataResps",goldCoinBuyerOrderDataResps);
            return res;
        }
    }

}
